<?php
namespace app\controller;

use Swoole\WebSocket\Server;
use think\facade\Db;

class Websocket
{
    protected $server;

    protected $redis;

    public function run()
    {

        $this->server = new Server('0.0.0.0', 2123);
        $this->server->set(['worker_num' => 2]);

        //$this->server->on('Start', [$this, 'start']);
        //$this->server->on('workerStart', [$this, 'workerStart']);

        $this->server->on('open', [$this, 'open']);
        $this->server->on('message', [$this, 'message']);
        $this->server->on('close', [$this, 'close']);
        $this->server->on('request', [$this, 'request']);
        //$this->server->on('handshake', [$this, 'handshake']);

        $this->server->start();
    }

    public  function  handshake  (\swoole_http_request $request, \swoole_http_response $response) {
        // print_r( $request->header );
        //通过判断websocket请求头当中是否有一个有效token
        if (!isset($request->header['sec-websocket-protocol'])) {
            //$response->end();
            //return false;
            //jwt验证
        }
        // websocket握手连接算法验证
        $secWebSocketKey = $request->header['sec-websocket-key'];
        $patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
        if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
            $response->end();
            return false;
        }
        echo $request->header['sec-websocket-key'];
        $key = base64_encode(sha1(
            $request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
            true
        ));

        $headers = [
            'Upgrade' => 'websocket',
            'Connection' => 'Upgrade',
            'Sec-WebSocket-Accept' => $key,
            'Sec-WebSocket-Version' => '13',
        ];

        // WebSocket connection to 'ws://127.0.0.1:9502/'
        // failed: Error during WebSocket handshake:
        // Response must not include 'Sec-WebSocket-Protocol' header if not present in request: websocket
        if (isset($request->header['sec-websocket-protocol'])) {
            $headers['Sec-WebSocket-Protocol'] = $request->header['sec-websocket-protocol'];
        }

        foreach ($headers as $key => $val) {
            $response->header($key, $val);
        }

        $response->status(101);
        $response->end();
    }

    public function workerStart($server, $workerId)
    {
        $this->redis = new Redis();
        //$this->redis->setOption();//设置超时时间
        $this->redis->pconnect('127.0.0.1', 6379);
    }

    public function request($request, $response)
    {
        echo 'request succ'.PHP_EOL;
        $data = $request->post;
        var_dump($request);
        //die;
        switch ($data['method']){
            case 'login':
                //1.权限验证
                //var_dump($data);
                //2.通过算法返回服务器地址
                break;
        }
    }

    public function open($server, $request)
    {
        echo "open succ".PHP_EOL;
        print_r(Db::name('user')->find(1));
    }

    public function message($server, $frame)
    {
        echo 'message succ'.PHP_EOL;
        var_dump($frame);
        /*$data = json_decode($frame->data, true);
        $fd = $frame->fd;
        switch ($data['method']){
            case 'register':
                $service_key = 'service:'.$data['serviceName'];
                echo $service_key.PHP_EOL;
                $value = ['ip' => $data['ip'], 'port' => $data['port']];
                $this->redis->sadd($service_key, json_encode($value));
                //会存在宕机的时候，主动清除
                $redis = $this->redis;
                $server->tick(3000, function ($id, $redis, $server, $server_key, $fd){
                    //检测fd,是否存活
                    if(!$server->exist((int)$fd)){
                        //删除redis中的服务器信息
                        //var_dump('im宕机了');
                        $redis->del($server_key);
                        //清除定时器
                        $server->clearTimer($id);
                        var_dump('im宕机了');
                    }
                }, $redis, $server, $service_key, $fd);
                break;
            case 'delete':
                break;
        }*/
    }

    public function close($server, $fd)
    {

    }
}
